package server

import (
	"fmt"
	"log"
	"net"
	"os"
	"runtime"
)

var (
	//监听业务端口
	localPort = 7000
	//监听client端口
	remotePort = 7001
)

type client struct {
	conn   net.Conn
	quit   chan int
	writer chan []byte
	reader chan []byte
}

type work struct {
	conn   net.Conn
	quit   chan int
	writer chan []byte
	reader chan []byte
}

func Start() {
	var (
		err            error
		clientListener net.Listener
		workListener   net.Listener
	)

	addr, _ := net.ResolveTCPAddr("tcp", fmt.Sprintf(":%d", remotePort))
	if clientListener, err = net.ListenTCP("tcp", addr); err != nil {
		log.Println(err)
		os.Exit(1)
	}
	log.Println("client listener start , port = ", remotePort)
	defer clientListener.Close()

	if workListener, err = net.Listen("tcp", fmt.Sprintf(":%d", localPort)); err != nil {
		log.Println(err)
		os.Exit(1)
	}
	log.Println("user listener start , port = ", localPort)
	defer workListener.Close()

	//业务端接入
	go func() {
		for {
			conn, e := workListener.Accept()
			if e != nil {
				log.Println(e)
				continue
			}

			w := &work{
				conn:   conn,
				writer: nil,
				reader: nil,
				quit:   make(chan int),
			}
			log.Printf("user request : remote addr = %v ", w.conn.RemoteAddr())
			userChan <- w
		}
	}()

	//客户端接入
	for {
		clientConn, e := clientListener.Accept()
		if e != nil {
			log.Println(e)
			continue
		}
		log.Println("client connect")

		c := &client{
			conn:   clientConn,
			writer: nil,
			reader: nil,
			quit:   make(chan int),
		}

		go c.handle()
	}
}

var userChan = make(chan *work)

//客户端处理器
func (c *client) handle() {
	for {
		select {
		case u := <-userChan:
			go func() {
				recvWork(u, c)
				recvClient(u, c)
			}()

		case <-c.quit:
			c.conn.Close()
			break
		}
	}
}

func recvWork(u *work, c *client) {
	for {
		buf := make([]byte, 4096)
		//rece, err := ioutil.ReadAll(u.conn)
		n, err := u.conn.Read(buf)

		if err != nil {
			log.Printf("user read error : %v", err)
			fmt.Println("user read==", u.conn.RemoteAddr())
			u.conn.Close()
			runtime.Goexit()
		}

		if n != 0 {
			log.Println(string(buf[:n]))
			c.conn.Write(buf[:n])
			log.Println("send client info")
			break
		}
	}
}

func recvClient(u *work, c *client) {
	buf := make([]byte, 4096)
	n, err := c.conn.Read(buf)

	if err != nil {
		log.Printf("user read error : %v", err)
		u.conn.Close()
		runtime.Goexit()
	}

	if n != 0 {
		log.Println(string(buf[:n]))
		if write, err := u.conn.Write(buf[:n]); err == nil {
			log.Println(write)
			log.Printf("user : %v", err)
			log.Println("send user info")
			fmt.Println("qqqqqqqqqqqqq==", u.conn.RemoteAddr())
			u.conn.Close()
		} else {
			log.Println("error======================")
			log.Println(err)
		}

	}

}

func (w *work) userHandle() {
	for {
		select {
		case <-w.quit:
			log.Println("user quit")
			w.conn.Close()
			break
		}
	}

}

func Quit(q chan int) {
	q <- 1
}

func Close(conn net.Conn) {
	conn.Close()

}
